<template>
  <form-generation
      :list="list"
      :config="config"
      ref="form"
      @afterInit="afterInit"
      @afterGetShowData="afterGetShowData"
      @close="close"
      @formChange="formChange"
  >
    <template #default>
      <!--表单和提交按钮之前的区域-->
    </template>
    <template #buttonPrefix="{ rawAuth }">
      <!--提交按钮的左侧-->
      <!--rawAuth表示菜单按钮权限-->
    </template>
    <template #button="{ rawAuth }">
      <!--提交按钮的右侧-->
      <!--rawAuth表示菜单按钮权限-->
    </template>
  </form-generation>
</template>
<script>
// 复杂表单的增删改查请使用这个组件，但这个组件由于历史遗留问题，BUG极多，有代码和页面表现不一样的情况，请及时反馈，不要怀疑自己
import FormGeneration from '@/components/common/dynamicForm/formGeneration/index.vue'
import {
  floodDangerInfoDangerInfoFailList,
  floodDangerInfoDangerInfoUpdate,
  floodExpertAttendanceExpertAttendanceAdd
} from '@/api/api-flood'

export default {
  components: { FormGeneration },
  data() {
    return {
      // 这个数据结构极其复杂以及难理解，但如果玩会了那表单页面可以实现任何复杂布局，核心就是数组嵌套以及children，建议跑DEMO理解【gcjsglxt/planandmoneymgr/planandmoneymgr】
      list: [
        [{
          // 分组名称
          title: '组',
          // 【常用】控制该组是否要在表单中展示，相当于v-show=false
          isEdit: true,
          // 分组
          children: [
            [{
              // 【必需】表单字段的标题
              title: '标题',
              // 【必需】表单中接口返回的字段名，也可以用于自定义的字段名，但下列特殊情况，字段名需要定义为数组
              // 如果type为'date'，且showType带'range'，即日期范围选择器，field必须要是['开始日期字段', '结束日期字段']
              // 如果type为'timePicker'，且isRange=true，即时间范围选择器，field必须要是['开始时间字段', '结束时间字段']
              // 如果type为'wkt'，且后端需要经纬度，即经纬度选择器，field必须要是['经度字段', '纬度字段']
              // 如果type为'upload'，且后端仅仅只需要文件路径、文件名（可不要），field必须要是['文件路径字段', '文件名字段']或['文件路径字段']
              field: 'title',
              // 【必需】组件类型,请参考"src/components/common/dynamicForm/formItemGeneration/index.vue"，搜索"item.type =="
              type: 'input',
              // 【常用】组件类型下有哪些配置项,请参考"src/components/common/dynamicForm/formItemGeneration/index.vue"，搜索"item.type =="
              disabled: false,
              size: 'small',
              width: '100%',
              ...各种各样的组件配置项,
              // 【常用】表单项对应的双向绑定值，一般无需设置，如果想要设置默认值，可以使用
              value: '默认值',
              // 【极其常用】表单中表单项的单位，会展示在表单项标题的后方，例如“金额（元）”
              unit: '单位',
              // 【常用】表单项对应的标题的样式
              customStyle: {
                width: '100%',
                fontWeight: 'bold',
                justifyContent: 'start'
              },
              // 【极其常用】校验条件，支持函数自定义，字符串（推荐），数组
              // 如果想设置内置的校验条件，例如必填等等，可以设置为字符串'required'，请参考"src/components/common/dynamicForm/formItemGeneration"，搜索"rules.forEach"
              // 如果想同时设置多个校验条件，可以设置为数组['required', 'float']
              rule: (data) => {
                // 可以使用getForm获取其余字段的value
                const otherValue = this.$refs.form.runCommand('getForm', {
                  target: 'otherField',
                  field: 'value'
                })
                if (data && data.length > 200) {
                  // 如果返回字符串，则会自动判断为校验失败，会在表单项下方展示出来这个字符串作为校验失败的提示
                  return '数据长度不能超过200位'
                } else if (otherValue && otherValue.length > 200) {
                  // 这里一定要注意，关联字段的修改并不会触发当前字段的校验，必须要搭配formChange事件和this.$refs.table.runCommand('refreshCheck')，手动触发一次校验
                  return '关联字段不能超过200位'
                } else {
                  return true
                }
              },
              // 【不常用】该表单项对应的标题盒子，支持用相对布局给标题周围新增一个图标，可以使用默认内置的图标，暂时只内置了“required”必填图标
              titleIcon: 'required',
              // 【不常用】该表单项对应的标题盒子，支持用相对布局给标题周围新增一个图标，除了默认内置的图标，也支持自定义图标，图标class可以参考“https://fontawesome.com.cn/v4/icons”
              titleIconClass: 'fa fa-asterisk',
              // 【不常用】该表单项对应的标题盒子，支持用相对布局给标题周围新增一个图标，除了默认内置的图标位置，也支持自定义位置
              titleIconStyle: {
                position: 'absolute',
                top: '-4px',
                left: '-9px',
                transform: 'scale(0.6)'
              }
            }]
          ]
        }]
      ],
      config: {
        // 【必需】后端接口实体中定义的ID字段，例如“id”，“fdId”等等
        id: 'id',
        // 【必需】表格列表查询需要用到的配置项
        show: {
          // 【必需】对传给后端的参数进行特殊处理
          queryFormat: () => {
            return {}
          },
          // 【常用】对后端返回的数据进行特殊处理
          format: (data) => {
            return data
          },
          // 【必需】表格列表查询用的接口
          method: floodDangerInfoDangerInfoFailList,
        },
        // 【极其常用】新增操作需要用到的配置项
        add: {
          // 【必需】新增用的接口
          method: floodExpertAttendanceExpertAttendanceAdd
        },
        // 【极其常用】编辑操作需要用到的配置项
        edit: {
          // 【必需】编辑用的接口
          method: floodDangerInfoDangerInfoUpdate
        },
        // 【极其常用】新增或编辑提交前，触发该回调，回调函数里可以对待提交的数据进行特殊处理
        sumitCallback: (data, rowData) => {
          // data：待提交的数据, rowData：编辑时初始化的数据源
          // 如果直接返回false，则会取消掉该次提价
          // return false
          return {
            ...data
          }
        },
        // 【不常用】新增或编辑提交后，触发该回调，res：接口返回的结果，data：提交给接口的数据, type：add/edit, rowData：编辑时初始化的数据源
        sumitAfterCallback: (res, data, type, rowData) => {
        },
        // 【不常用】组件初始化是是否要请求接口
        loadFirst: true,
        // 【不常用】是否隐藏表单下方的提交按钮
        submitAble: true,
        // 【不常用】一般来说按钮权限都是组件自动根据URL路径后缀获取，但有些特殊情况，例如菜单A和菜单B都需要使用该组件，按钮权限要求都使用菜单A的，那这里就必须要把获取按钮权限的URL路径后缀写死
        authPath: 'projectfinishaccept'
      }
    }
  },
  methods: {
    // 【极其常用】表单从接口获取到初始化数据之后会调用此事件
    // data是表单初始化用到的数据源，type是add/edit，isFirst是表单是否是初次加载数据
    afterGetShowData(data, type, isFirst) {
    },
    // 【极其常用】组件初始化完成的回调，任何对表单相关的处理，必须要在此函数内执行
    afterInit() {
      // 【极其常用】【极其重要】组件只暴露出runCommand一个方法供开发使用，绝对不允许通过$refs.form获取其他属性或方法进行调用或修改
      // 请参考"src/components/common/dynamicForm/formGeneration/index.vue"，搜索"runCommand ("
      this.$refs.form.runCommand()
    },
    // 【极其常用】表单项触发事件的回调
    // field是表单项的field, eventName是表单项触发的事件名, e是表单项触发的事件回调的参数
    formChange (field, eventName, e) {
      // 监听事件一定要写明field和eventName，绝对不能偷懒，否则会造成多次触发
      // 例如只写了“field === 'title'”，但title表单项存在多个事件，最后，所有这个表单项的事件都会触发这段代码
      if (field === 'title' && eventName === 'change') {
        console.log(e)
      }
    },
    // 【常用】表单点击提交，然后接口成功返回结果后，会触发此回调
    // data是接口返回的数据
    close(data) {
    },
  }
}
</script>
